/*
 *  PureTemperament.cpp
 *  SoundController0002
 *
 *  Created by jiro on 10/10/02.
 *  Copyright 2010 jiro music. All rights reserved.
 *
 */

#include "PureTemperament.h"
#include "AllExceptions.h"
#include <cmath>

namespace sc {

	double PureTemperament::GetFrequency( Note::Id rootNoteId, Note::Id noteId, int octave )
	{
		throw NotImplementedException( __FUNCTION__ );
		return 0;
	}

	double PureTemperament::GetIntervalRate( Note::Id fromNoteId, Note::Id toNoteId )
	{
		int lowerNote = fromNoteId;
		int upperNote = toNoteId;
		
		while ( lowerNote > upperNote ) {
			lowerNote -= 12;
		}

		switch ( upperNote - lowerNote ) {
		case 0:
			return 1.0;
		case 1:
			return 16.0 / 15.0;
		case 2:
			return 9.0 / 8.0;
		case 3:
			return 6.0 / 5.0;
		case 4:
			return 5.0 / 4.0;
		case 5:
			return 4.0 / 3.0;
		case 6:
			return 7.0 / 5.0;
		case 7:
			return 3.0 / 2.0;
		case 8:
			return 8.0 / 5.0;
		case 9:
			return 5.0 / 3.0;
		case 10:
			return 16.0 / 9.0;
		case 11:
			return 15.0 / 8.0;
		default:
			throw ApplicationErrorException( __FUNCTION__ );
		}
		return 0;
	}

	double PureTemperament::GetIntervalRate( Note::Id fromNoteId, int fromNoteOctave, Note::Id toNoteId, int toNoteOctave )
	{
		const int fromNoteNumber = fromNoteId + Note::NoteCount * fromNoteOctave;
		const int toNoteNumber = toNoteId + Note::NoteCount * toNoteOctave;
		int octave = ( toNoteNumber - fromNoteNumber ) / 12.;
		if ( ( toNoteNumber - fromNoteNumber ) % 12 < 0 ) {
			octave--;
		}
		double rate = GetIntervalRate( fromNoteId, toNoteId );
		return pow( 2, octave ) * rate;
	}

}
